Heute beschäftigen wir uns mit der Darstellung komplexerer Ausdrücke der Relationenalgebra mithilfe von Operatorbäumen und betrachten dazu verschiedene Beispiele. Der Operatorbaum ist ein zentrales Werkzeug, um die Abfolge und Verschachtelung relationaler Operationen übersichtlich zu visualisieren. Warum nutzen wir eine Baumdarstellung? Gerade bei komplexeren Ausdrücken bietet sich die Baumstruktur an, da sie es erlaubt, auch verschachtelte Operationen klar darzustellen. Wir lesen diese Bäume von unten nach oben. Unäre Operationen – also solche mit nur einem Eingabe-Zweig – und binäre Operationen – mit zwei Eingaben – werden so direkt sichtbar. Dadurch ist die Abfrage besser nachvollziehbar als in rein linearer Notation. Hier ein Beispiel für einen Operatorbaum: Die Aufgabe lautet, die Titel und Nummern aller Vorlesungen zu finden, die der Student Xenokrates gehört hat. Überlegen Sie sich bitte kurz, wie Sie so eine Abfrage überhaupt strukturieren würden. Wir werden das gleich anhand des Operatorbaums durchgehen. Die Lösung zu dieser Aufgabe sieht in SQL so aus: Wir verknüpfen also mehrere Relationen über Joins, wobei wir gezielt nur die Daten des Studenten Xenokrates betrachten. Im Ausdruck der Relationenalgebra sehen wir, wie die Selektion auf den Studenten zuerst in den innersten Klammern ausgeführt wird und die Ergebnisse anschließend mit den Vorlesungen und der Teilnahme („hören“) verknüpft werden. Abschließend erfolgt die Projektion. Und hier sehen Sie den vollständigen Operatorbaum zu dieser Aufgabe. Beachten Sie, dass wir bei der Ausführung stets von unten beginnen – also zuerst die Selektion, dann die Joins und am Ende die Projektion auf die gewünschten Attribute. So wird die Reihenfolge der Operationen transparent. Auf dieser Folie bitte ich Sie, selbst zu überlegen: Was soll bei dieser Abfrage eigentlich gefunden werden? Und wie würden Sie hier den passenden SQL-Befehl formulieren? Sie können den SQL-Befehl direkt aus dem Operatorbaum ableiten! Versuchen Sie es! Wir kommen nun zu mehreren Beispielen aus der Relationenalgebra, um die einzelnen Operatoren und deren Zusammenspiel besser kennenzulernen. Damit festigen wir die Grundlagen für den Umgang mit komplexeren Abfragen. Für unsere Beispiele nutzen wir drei Relationen: Kunde, Lieferant und Ware. Hier sehen Sie die zugehörigen Schemata. Notieren Sie sich bitte, welche Attribute jede Relation enthält, da wir diese gleich für unterschiedliche Abfragen benötigen. Hier sehen Sie, wie wir die Grundoperationen der Relationenalgebra konkret anwenden. Beispielsweise filtern wir alle Lieferanten aus Bremen mit einer Selektion, oder wir listen alle Preise und Bezeichnungen von Waren mit einer Projektion auf. Durch die Umbenennung können wir auch Attributnamen anpassen, zum Beispiel um spätere Joins zu erleichtern. Da die Ergebnisse relationaler Operationen wieder Relationen sind, können wir beliebig viele Operationen kombinieren. Für mehr Übersicht werden beim Kreuzprodukt die Attributnamen oft mit dem Relationsnamen qualifiziert – das erleichtert später die Unterscheidung, beispielsweise wenn mehrere Relationen das Attribut „Lieferantennummer“ besitzen. Hier sehen wir zwei weitere Beispiele: Erstens: Wir bestimmen die Telefonnummern aller Lieferanten, die Gemüse in Bremen liefern. Dazu kombinieren wir Selektion, Join und Projektion. Zweitens: Um alle Orte zu finden, in denen es mindestens einen Kunden und mindestens einen Lieferanten gibt, nutzen wir die Schnittmenge zweier Projektionen. Solche Verkettungen sind typisch für anspruchsvollere Datenbankabfragen. Nun wechseln wir das Beispiel und schauen uns klassische Abfragen im Kontext von Mitarbeitern und Abteilungen an. Das ist ein sehr häufiges Anwendungsszenario in Unternehmen, und die Schemata sehen meist folgendermaßen aus: Wir haben eine Relation „Mitarbeiter“ mit Attributen wie Mitarbeiternummer, Name, Gehalt, Abteilungsnummer usw. und eine Relation „Abteilung“ mit Attributen wie Abteilungsnummer und Abteilungsname. Wir interessieren uns jetzt beispielsweise für Fragen wie: Welche Mitarbeiter arbeiten in welcher Abteilung? Wie viele Mitarbeiter gibt es pro Abteilung? Welche Abteilung hat die höchsten Durchschnittsgehälter? Die Operatoren der Relationenalgebra – insbesondere Join, Projektion und Aggregation – sind hier essenziell, um solche Abfragen zu formulieren. In der relationalen Algebra können wir einen Join zwischen „Mitarbeiter“ und „Abteilung“ auf Basis der Abteilungsnummer bilden, um Informationen aus beiden Relationen in einem Ergebnis zu kombinieren. Das ist die Grundlage für viele Auswertungen, die im Personalwesen relevant sind. Wir werden uns im nächsten Schritt konkrete Operatorausdrücke und SQL-Beispiele für solche Abfragen ansehen. Auf dieser Folie sehen Sie nun konkrete Beispiele für typische Abfragen zu Mitarbeitern und Abteilungen – sowohl in relationaler Algebra als auch als SQL-Befehl. Zum Beispiel könnten wir fragen: Gib alle Namen der Mitarbeiter aus, die in der Abteilung „Vertrieb“ arbeiten. Das würde in der relationalen Algebra bedeuten, dass wir zunächst einen Join zwischen „Mitarbeiter“ und „Abteilung“ auf Abteilungsnummer durchführen, danach eine Selektion auf Abteilungsname = „Vertrieb“, und zum Schluss eine Projektion auf den Namen der Mitarbeiter. Oder eine andere Frage: Welche Abteilungen haben mehr als fünf Mitarbeiter? Hier benötigen wir eine Gruppierung nach Abteilung, eine Zählung der Mitarbeiter und eine Selektion auf die Gruppen mit mehr als fünf Einträgen. Solche Abfragen zeigen den typischen Workflow: erstens: Relationen verbinden (Join), zweitens: Bedingungen anwenden (Selektion), drittens: Ergebnis einschränken (Projektion) und optional: Aggregation und Gruppierung. Achten Sie darauf, die Operatoren in der richtigen Reihenfolge anzuwenden. Diese Art von Abfragen ist im Alltag extrem wichtig, beispielsweise für das Reporting im Personalbereich oder bei Managementauswertungen. Hier sehen Sie, wie die zuvor diskutierten Anfragen in SQL übersetzt werden können. Vergleichen Sie die SQL-Syntax mit den Operatoren der Relationenalgebra. Die beiden Notationen sind immer direkt ineinander überführbar. Gegeben ist ein Relationsschema mit zwei Relationen: „Städte“ und „Länder“. Die Relation „Städte“ enthält die Attribute der Name der Stadt, Einwohnerzahl der Stadt und Land. Also der Name des Landes, in dem die Stadt liegt. Die Relation „Länder“ enthält die Attribute Name des Landes, die Einwohnerzahl des Landes und Partei. Der Stern bei Partei weist darauf hin, dass es sich bei Koalitionsregierungen um mehrere Tupel mit jeweils einer Partei handeln kann. Darauf aufbauend werden drei Aufgaben mit relationaler Algebra formuliert: Erstens: Zur Bestimmung aller Großstädte mit mindestens fünfhunderttausend Einwohnern und ihrer jeweiligen Einwohnerzahl wird eine Selektion auf die Relation „Städte“ angewendet. Danach erfolgt eine Projektion. Zweitens: Um herauszufinden, in welchem Land die Stadt Passau liegt, wird eine Selektion mit einer Bedingung durchgeführt, gefolgt von einer Projektion auf das Attribut Land. Drittens: Zur Bestimmung aller Städtenamen, deren Einwohnerzahl die eines beliebigen Landes übersteigt, wird zunächst das kartesische Produkt von „Städte“ und „Länder“ gebildet. Darauf folgt eine Selektion mit einer Bedingung. Anschließend wird auf ein Attribut projiziert. Gegeben ist wieder das gleiche Relationsschema mit zwei Relationen: „Städte“ mit den Attributen Stadtname, Einwohnerzahl und zugehöriges Land sowie „Länder“ mit Landesname, Einwohnerzahl und einer oder mehreren regierenden Parteien. Bei Koalitionsregierungen existiert für jede Partei ein separates Tupel. Zunächst soll ermittelt werden, welche Städte in CDU-regierten Ländern liegen. Dazu wird die Menge aller Länder bestimmt, in denen die Partei CDU in der Regierung ist. Anschließend wird diese Menge mit der Relation „Städte“ verknüpft, wobei jeweils die Länderbezeichnung verglichen wird. Abschließend werden die Namen der Städte extrahiert, die auf diese Weise als CDU-regiert identifiziert wurden. Alternativ kann dies auch durch eine direkte Bedingung innerhalb des kartesischen Produkts erfolgen, indem gleichzeitig geprüft wird, ob der Landesname mit dem in der Stadt übereinstimmt und ob das betreffende Land von der CDU regiert wird. In der zweiten Aufgabe soll bestimmt werden, welche Länder ausschließlich von der SPD regiert werden. Dazu wird zunächst die Menge aller Länder bestimmt, in denen die SPD eine Regierungspartei ist. Davon wird dann die Menge aller Länder subtrahiert, in denen auch andere Parteien (also nicht die SPD) mitregieren. Das Ergebnis ist die Menge jener Länder, die ausschließlich von der SPD regiert werden, also ohne Koalitionspartner. Im Folgenden gehen wir auf besonders einfache, aber typische Aufgabenstellungen ein, um Ihnen den Einstieg in die praktische Anwendung der Relationenalgebra zu erleichtern. Diese Beispiele eignen sich gut für die Übung zu Hause oder als Grundlage für eigene Abfragen. Hier sehen Sie, wie die Selektion in der Praxis umgesetzt wird. Wir filtern beispielsweise alle Rechnungen eines bestimmten Kunden, Bestellungen vor einem bestimmten Datum oder Produkte unter einem bestimmten Preis. Die Selektion ist einer der grundlegendsten Operatoren in der Relationenalgebra und findet ihre Entsprechung direkt im SQL-Statement „where“. Die Projektion erlaubt es uns, gezielt bestimmte Spalten einer Relation auszuwählen. Achten Sie darauf, dass Projektion und Selektion sich sinnvoll kombinieren lassen, um das Ergebnis genau auf die gewünschten Daten einzuschränken. Und das sind passende Ausdrücke in der Relationenalgebra dazu. Der Join ist ein zentraler Operator, um Informationen aus mehreren Relationen zu verknüpfen. Hier sehen wir Beispiele für einen Join zwischen Kunden und ihren Rechnungen sowie zwischen Rechnungspositionen und Produktdetails und den jeweils dazu entsprechenden Ausdruck der Relationenalgebra. Abschließend noch das Kreuzprodukt: Es kombiniert jede Zeile der ersten Relation mit jeder Zeile der zweiten. In SQL erhalten wir das Kreuzprodukt, wenn wir mehrere Tabellen ohne Where-Bedingung kombinieren. Im praktischen Einsatz wird das Kreuzprodukt meist mit einer Selektion kombiniert, um einen Join zu realisieren – rein als Kreuzprodukt ist es selten sinnvoll.